﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Collections;
using ModelUML;

namespace Parser
{
    public class Parse
    {
        public enum PARSETYPE { ATTRIBUTE, METHOD };

        public Diagram.Element konwertujNaModel(Hashtable table)
        {
            Diagram.Element e = null;

            if (table != null)
            {
                if ((bool)table["success"] == true)
                {
                    PARSETYPE type = (PARSETYPE)table["type"];
                    if (type == PARSETYPE.ATTRIBUTE)
                    {
                        String rodzaj = (String)table["rodzaj"]; // # + -
                        String typ = (String)table["typ"];
                        String nazwa = (String)table["nazwa"];
                        int krotnosc = (int)table["krotnosc"];
                        e = new Diagram.Atrybut(nazwa, krotnosc == 0 ? typ : typ + "[" + krotnosc + "]");
                        e.Visibility = rodzaj;                        

                    }
                    else if (type == PARSETYPE.METHOD)
                    {
                        String rodzaj = (String)table["rodzaj"];
                        String nazwa = (String)table["nazwa"];
                        String typ_zwracanay = (String)table["typ_zwracany"];
                        ArrayList atrybuty = (ArrayList)table["lista_argumentow"];
                        e = new Diagram.Operacja(nazwa, typ_zwracanay);
                        e.Visibility = rodzaj;
                        foreach (object o in atrybuty)
                        {
                            if (o is Hashtable)
                            {
                                Hashtable hO = o as Hashtable;
                                String atrybut_nazwa = (String)hO["argument_nazwa"];
                                String atrybut_type = (String)hO["argument_typ"];
                                int krotnosc = (int)hO["krotnosc"];
                                ((Diagram.Operacja)e).DodajAtrybut(new Diagram.Atrybut(atrybut_nazwa,krotnosc ==0?atrybut_type:atrybut_type+"["+krotnosc+"]"));
                            }
                        }
                    }
                }
            }

            return e;
        }
        
        public Hashtable parsujAtrybut(String tekst)
        {
        // Tablica asocjacyjna
        Hashtable result = new Hashtable();
        result.Add("success", false);        

        Regex WyrazenieRegularne = new Regex(@"([\-+#])?[ ]*([A-Za-z0-9_]{1,})[ ]*:[ ]*([A-Za-z0-9_]{1,})(\[(\d{1,})\])?");

        Match Rezultat = WyrazenieRegularne.Match(tekst);
	    if(Rezultat.Success)
            {
            // success = true
            result.Clear();
            result.Add("type", PARSETYPE.ATTRIBUTE);
            result.Add("success", true);

            // 1 - Rodzaj
            String rodzaj = "-";
            if (Rezultat.Groups[1].Success)
                rodzaj = Rezultat.Groups[1].Value;
            result.Add("rodzaj", rodzaj);

            // 2 - Nazwa
            if (!Rezultat.Groups[2].Success)
                return null;
            String nazwa = Rezultat.Groups[2].Value;
            result.Add("nazwa", nazwa);

            // 3 - Typ
            if (!Rezultat.Groups[3].Success)
                return null;
            String typ = Rezultat.Groups[3].Value;
            result.Add("typ", typ);

            // 5 - Krotnosc (opcjonalna)
            int krotnosc = 0;
            if (Rezultat.Groups[5].Success)
                krotnosc = Convert.ToInt32(Rezultat.Groups[5].Value);
            result.Add("krotnosc", krotnosc);
            }

        return result;
        }

        public Hashtable parsujMetode(String tekst)
            {
            // Tablica asocjacyjna
            Hashtable result = new Hashtable();
            result.Add("success", false);
            
            Regex WyrazenieRegularne = new Regex(@"([\-+#])?[ ]*([A-Za-z0-9_]{1,})[ ]*\(([^)]*)\)[ ]*:[ ]*([A-Za-z0-9_]{1,})");
            Match Rezultat = WyrazenieRegularne.Match(tekst);
             if (Rezultat.Success)
                {
                // success = true
                result.Clear();
                result.Add("type", PARSETYPE.METHOD);
                result.Add("success", true);

                // 1 - Rodzaj
                String rodzaj = "-";
                if (Rezultat.Groups[1].Success)
                    rodzaj = Rezultat.Groups[1].Value;
                result.Add("rodzaj", rodzaj);

                // 2 - Nazwa
                if (!Rezultat.Groups[2].Success)
                    return null;
                String nazwa = Rezultat.Groups[2].Value;
                result.Add("nazwa", nazwa);

                // 4 - Typ zwracany
                if (!Rezultat.Groups[4].Success)
                    return null;
                String typ_zwracany = Rezultat.Groups[4].Value;
                result.Add("typ_zwracany", typ_zwracany);

                ArrayList lista_argumentow = new ArrayList();

                // 3 - Argumenty (opcjonalne)
                if (Rezultat.Groups[3].Success)
                    {
                    
                    String ArgumentyTekst = Rezultat.Groups[3].Value;
                    string[] Argumenty = null;
                    Argumenty = Regex.Split(ArgumentyTekst, ",");
                    Regex WyrazenieRegularne2 = new Regex(@"([A-Za-z0-9_]{1,})(\[(\d{1,})\])?[ ]*:[ ]*([A-Za-z0-9_]{1,})");
                    Match RezultatArgumenty;
                    Hashtable argument;
                    foreach (String Argument in Argumenty)
                        {
                        RezultatArgumenty = WyrazenieRegularne2.Match(Argument);
                        
                        if (RezultatArgumenty.Groups[1].Success == true && RezultatArgumenty.Groups[4].Success == true)
                            {
                            argument = new Hashtable(3);
                            int krotnosc = 0;
                            String ArgumentNazwa = RezultatArgumenty.Groups[1].Value;
                            argument.Add("argument_nazwa", ArgumentNazwa);
                            if (RezultatArgumenty.Groups[3].Success)
                                krotnosc = Convert.ToInt32(RezultatArgumenty.Groups[3].Value);
                            argument.Add("krotnosc", krotnosc);
                            String ArgumentTyp = RezultatArgumenty.Groups[4].Value;
                            argument.Add("argument_typ", ArgumentTyp);
                            lista_argumentow.Add(argument);
                            }

                        }
                    }
                result.Add("lista_argumentow", lista_argumentow);
                }

            return result;
            }

    }
}